# -*- coding: utf-8 -*-
# @File: backend => websocket_api.py
# @CreateTime: 2025/8/27 13:30
# @Author: EvanZhang
# @Info: WebSocket API服务 - 提供实时通信功能
"""
WebSocket API模块

本模块提供WebSocket实时通信服务，主要功能包括：
1. 客户端连接管理 - 建立、维护和断开WebSocket连接
2. 消息处理 - 接收、解析和响应客户端消息
3. 心跳机制 - 保持连接活跃，检测连接状态
4. 消息广播 - 支持个人消息和群组广播
5. 异常处理 - 优雅处理连接异常和资源清理

支持的消息类型：
- ping/pong: 心跳检测
- message: 普通聊天消息
- connection: 连接状态通知
- user_joined/user_left: 用户进入/离开通知
"""

from fastapi import APIRouter, WebSocket, WebSocketDisconnect, Depends
from typing import List
from fastapi.responses import HTMLResponse
import asyncio
import json
import logging

from apps.utils.websocket import WebSocketConnectionManager
from apps.utils.jwt import verify_jwt_token

# 配置日志记录器
logger = logging.getLogger(__name__)

# 创建WebSocket路由器，统一管理WebSocket相关接口
websockets = APIRouter(prefix='/ws', tags=['WebSocket相关'])

# 创建一个WebSocket连接管理器实例，用于客户端接收房间消息
room_manager = WebSocketConnectionManager()
@websockets.websocket('/{client_id}')
async def websocket_endpoint(websocket: WebSocket, client_id: int):
    """
    WebSocket连接端点
    
    Args:
        websocket: WebSocket连接对象
        client_id: 客户端唯一标识ID
    
    功能说明:
        - 处理WebSocket连接的建立、消息收发和断开
        - 支持心跳机制保持连接活跃
        - 支持消息广播和个人消息发送
        - 自动处理连接异常和清理资源
    """
    # 建立WebSocket连接
    await room_manager.connect(websocket)
    logger.info(f"客户端 #{client_id} 已连接")
    
    # 发送连接成功消息给当前客户端
    await room_manager.send_personal_message({
        "type": "connection",
        "message": f"客户端 #{client_id} 已连接成功",
        "client_id": client_id
    }, websocket)
    
    # 通知其他在线客户端有新用户加入
    await room_manager.broadcast({
        "type": "user_joined",
        "message": f"客户端 #{client_id} 已加入聊天",
        "client_id": client_id
    }, exclude_websocket=websocket)
    
    try:
        # 主消息循环 - 持续监听客户端消息
        while True:
            # 接收客户端消息，依赖FastAPI内置的连接检测
            data = await websocket.receive_text()

            # 尝试解析JSON格式的消息
            try:
                message_data = json.loads(data)
                message_type = message_data.get("type", "message")

                if message_type == "ping":
                    # 客户端发送ping，服务器响应pong（心跳检测）
                    await room_manager.send_personal_message({
                        "type": "pong",
                        "timestamp": message_data.get("timestamp")
                    }, websocket)
                elif message_type == "message":
                    # 处理普通聊天消息
                    content = message_data.get("content", data)
                    # 向发送者回显消息确认
                    await room_manager.send_personal_message({
                        "type": "echo",
                        "message": f"你发送了: {content}",
                        "client_id": client_id
                    }, websocket)
                    # 广播消息给其他在线客户端
                    await room_manager.broadcast({
                        "type": "broadcast",
                        "message": f"客户端 #{client_id} 说: {content}",
                        "client_id": client_id
                    }, exclude_websocket=websocket)
                else:
                    # 处理其他类型消息 - 给发送者返回错误信息
                    await room_manager.send_personal_message({
                        "type": "error",
                        "message": f"未知消息类型: {message_type}",
                        "client_id": client_id
                    }, websocket)
                    logger.warning(f"客户端 #{client_id} 发送了无效的消息类型: {message_type}")
                    # await room_manager.broadcast({
                    #     "type": "broadcast",
                    #     "message": f"客户端 #{client_id} 说: {data}",
                    #     "client_id": client_id
                    # }, exclude_websocket=websocket)

            except json.JSONDecodeError:
                # JSON解析失败，返回格式错误信息
                await room_manager.send_personal_message({

                    "type": "error",
                    "message": "消息格式错误，请发送有效的JSON格式消息",
                    "client_id": client_id,
                    "received_data": data
                }, websocket)
                logger.warning(f"客户端 #{client_id} 发送了无效的JSON消息: {data}")

    except WebSocketDisconnect:
        # WebSocket正常断开连接
        logger.info(f"客户端 #{client_id} 正常断开连接")
    except Exception as e:
        # 处理其他异常
        logger.error(f"客户端 #{client_id} 发生错误: {e}")
    finally:
        # 资源清理阶段
        # 从连接管理器中移除当前连接
        room_manager.disconnect(websocket)

        # 通知其他在线客户端该用户已离开
        await room_manager.broadcast({
            "type": "user_left",
            "message": f"客户端 #{client_id} 已离开聊天",
            "client_id": client_id
        })

        logger.info(f"客户端 #{client_id} 清理完成")